import requests
from typing import Union
from typing import Optional
import settings
import json
import datetime
from logger_config import setup_logger
from snownlp import SnowNLP
import re

# 设置日志记录器
logger = setup_logger()


class BiliVideoinfo(object):

    def __init__(self, bv_id: str):
        self.bv_id = bv_id
        try:
            # 发起请求并解析 JSON
            response = requests.get(f'{settings.VIDEO_API_ADDRESS}/api/bilibili/web/fetch_one_video?bv_id={bv_id}')
            response.raise_for_status()  # 确保响应成功，否则抛出HTTPError
            data = response.json()

            # 从嵌套的数据中提取有效信息
            video_data = data.get('data', {}).get('data', {})
            self.aid = video_data.get('aid')
            self.title = video_data.get('title')
            self.desc = video_data.get('desc')
            self.owner = video_data.get('owner', {}).get('name')
            self.view = video_data.get('stat', {}).get('view')
            self.like = video_data.get('stat', {}).get('like')
            self.reply = video_data.get('stat', {}).get('reply')

        except requests.exceptions.RequestException as e:
            # 捕获请求相关的错误（包括网络问题、无效的响应等）
            logger.error(f"Error occurred while fetching Bilibili video info for {bv_id}: {e}")
            self.aid = self.title = self.desc = self.owner = self.view = self.like = self.reply = None

        except ValueError as e:
            # 捕获 JSON 解析错误
            logger.error(f"JSON decode error for Bilibili video {bv_id}: {e}")
            self.aid = self.title = self.desc = self.owner = self.view = self.like = self.reply = None

        except Exception as e:
            # 捕获所有其他类型的错误
            logger.error(f"Unexpected error for Bilibili video {bv_id}: {e}")
            self.aid = self.title = self.desc = self.owner = self.view = self.like = self.reply = None

    def get_info(self) -> dict:
        info = {
            'bv_id': self.bv_id,
            'aid': self.aid,
            'title': self.title,
            'desc': self.desc,
            'owner': self.owner,
            'view': self.view,
            'like': self.like,
            'reply': self.reply
        }
        return info

    def get_comments(self, pn: int) -> list:
        comment_list = list()
        try:
            # 发起请求并解析 JSON
            response = requests.get(
                f'{settings.VIDEO_API_ADDRESS}/api/bilibili/web/fetch_video_comments?bv_id={self.bv_id}&pn={pn}')
            response.raise_for_status()  # 确保响应成功，否则抛出HTTPError
            data = response.json()

            # 从嵌套的数据中提取有效信息
            comment_data = data.get('data', {}).get('data', {}).get('replies', [])
            for comment in comment_data:
                comment_dict = dict()
                comment_dict['comment_text'] = comment.get('content').get('message')
                # 将ctime转换为datetime对象
                date_time = datetime.datetime.fromtimestamp(comment.get('ctime'))
                comment_dict['comment_time'] = date_time
                comment_dict['user_id'] = comment.get('member').get('mid')
                comment_dict['user_nickname'] = comment.get('member').get('uname')
                comment_dict['user_sex'] = comment.get('member').get('sex')
                comment_dict['sub_comment_count'] = comment.get('rcount')
                comment_dict['likes'] = comment.get('like')
                text = comment.get('reply_control').get('location')
                # 使用正则表达式提取省份名
                pattern = r"IP属地：(.+)"
                match = re.search(pattern, text)
                if match:
                    province = match.group(1)
                    comment_dict['address'] = province
                else:
                    comment_dict['address'] = None
                # 创建 SnowNLP 对象
                s = SnowNLP(comment_dict['comment_text'])
                # 获取情感值，范围为 0 到 1，接近 1 表示积极情感，接近 0 表示消极情感
                sentiment = s.sentiments
                if sentiment < 0.1:
                    sentiment = sentiment + 0.5
                # 四舍五入到小数点后三位
                rounded_sentiment = round(sentiment, 3)
                comment_dict['emotional_value'] = rounded_sentiment
                comment_dict['video_id'] = self.aid
                comment_list.append(comment_dict)

        except requests.exceptions.RequestException as e:
            # 捕获请求相关的错误（包括网络问题、无效的响应等）
            logger.error(f"Error occurred while fetching Bilibili video info for {self.aid} pn {pn}: {e}")
            comment_list = None

        except ValueError as e:
            # 捕获 JSON 解析错误
            logger.error(f"JSON decode error for Bilibili video {self.aid} pn {pn}: {e}")
            comment_list = None

        except Exception as e:
            # 捕获所有其他类型的错误
            logger.error(f"Unexpected error for Bilibili video {self.aid} pn {pn}: {e}")
            comment_list = None

        return comment_list


if __name__ == '__main__':
    one = BiliVideoinfo('BV1nMHze4Ev3')
    print(one.get_info())
    print(one.get_comments(1))
